package cn.me.alphamq.common.msg;

import cn.me.alphamq.common.constant.GlobalConstant;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageCodec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 * tcp 连接中消息的编解码器
 *
 * @author f
 */
public class TcpMsgCodec extends ByteToMessageCodec<TcpMsg> {

    private static final Logger log = LoggerFactory.getLogger(TcpMsgCodec.class);

    // 对消息进行解码
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        // 检查数据包是否完整
        if (in.readableBytes() < TcpMsg.MIN_LEN) {
            log.error("数据包不完整");
            ctx.close();
            return;
        }

        // 检查魔数是否正确
        if (in.readShort() != GlobalConstant.MAGIC_NUM) {
            log.error("魔数不正确");
            ctx.close();
            return;
        }

        int code = in.readInt();
        int len = in.readInt();

        // 校验 msg 的主体是否完整
        if (in.readableBytes() < len) {
            log.error("msg 的 body 不完整");
            ctx.close();
            return;
        }

        // 读取 msg 的主体
        byte[] body = new byte[len];
        in.readBytes(body);

        // 封装 TcpMsg 对象，并将其放入链表中，让下一个处理器处理
        out.add(new TcpMsg(code, body));
    }

    // 对消息进行编码
    @Override
    protected void encode(ChannelHandlerContext ctx, TcpMsg tcpMsg, ByteBuf out) throws Exception {
        out.writeShort(tcpMsg.getMagic());
        out.writeInt(tcpMsg.getCode());
        out.writeInt(tcpMsg.getLen());
        out.writeBytes(tcpMsg.getBody());
    }
}
